﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using ProduceBasicData.Api.DTO.InvoiceAndReceiptDto;
using ProduceBasicData.Domain.InvoiceAndReceiptManage;
using ProduceBasicData.Domain.InvoiceAndReceiptManage.Enum;

using ProduceBasicData.Infrastructure.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace ProduceBasicData.Api.Controllers.InvoiceAndReceiptManage
{
    [Route("api/[controller]")]
    [ApiController]
    public class ExcelController : ControllerBase
    {
        private readonly IBaseRespository<Invoice> _invoiceRepository;
        private readonly IBaseRespository<Receipt> _receiptRepository;

        public ExcelController(IBaseRespository<Invoice> invoiceRepository,
                               IBaseRespository<Receipt> receiptRepository)
        {
            _invoiceRepository = invoiceRepository;
            _receiptRepository = receiptRepository;
        }

        #region 导出功能（保持原有逻辑，无需修改）
        /// <summary>
        /// 导出发票数据为Excel
        /// </summary>
        /// <param name="keyword">查询关键词（开票单号/收票方/销售单号）</param>
        [HttpGet("ExportInvoice")]
        public async Task<IActionResult> ExportInvoice([FromQuery] string? keyword = null)
        {
            try
            {
                var invoiceList = await _invoiceRepository.GetAllAsync();
                var query = invoiceList.Where(x => x.Isdel == false);

                if (!string.IsNullOrEmpty(keyword))
                {
                    query = query.Where(x =>
                        (x.SystemNo != null && x.SystemNo.Contains(keyword)) ||
                        (x.Payee != null && x.Payee.Contains(keyword)) ||
                        (x.SalesOrderNo != null && x.SalesOrderNo.Contains(keyword)));
                }

                var exportModels = query.Select(x => new
                {
                    Id = x.Id,
                    系统编号 = x.SystemNo,
                    开票主题 = x.InvoiceSubject,
                    发票类型 = x.InvoiceType,
                    开票日期 = x.InvoiceDate?.ToString("yyyy-MM-dd"),
                    是否绑定销售订单 = x.IsBindSalesOrder ? "是" : "否",
                    收票方 = x.Payee,
                    发票号 = x.InvoiceNo,
                    销售单号 = x.SalesOrderNo,
                    销售订单主题 = x.SalesOrderSubject,
                    发票金额 = x.Amount,
                    出库状态 = x.OutboundStatus,
                    开票状态 = GetInvoiceStatusText(x.Status),
                    创建人 = x.CreateName,
                    创建时间 = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    更新人 = x.UpdateName,
                    更新时间 = x.UpdateTime?.ToString("yyyy-MM-dd HH:mm:ss")
                }).ToList();

                var stream = new MemoryStream();
                await stream.SaveAsAsync(exportModels);
                stream.Position = 0;

                var fileName = $"发票数据_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                return File(
                    fileStream: stream,
                    contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sxlsx",
                    fileDownloadName: fileName
                );
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { success = false, message = $"导出失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 导出到票数据为Excel
        /// </summary>
        /// <param name="keyword">查询关键词（发票号）</param>
        [HttpGet("ExportReceipt")]
        public async Task<IActionResult> ExportReceipt([FromQuery] string? keyword = null)
        {
            try
            {
                var receiptList = await _receiptRepository.GetAllAsync();
                var query = receiptList.Where(x => x.Isdel == false);

                if (!string.IsNullOrEmpty(keyword))
                {
                    query = query.Where(x => x.InvoiceNo != null && x.InvoiceNo.Contains(keyword));
                }

                var exportModels = query.Select(x => new
                {
                    Id = x.Id,
                    到票单号 = x.SytemNo,
                    到票主题 = x.ReceiptSubject,
                    到票日期 = x.ReceiptDate?.ToString("yyyy-MM-dd"),
                    开票方 = x.InvoiceIssuer,
                    发票号 = x.InvoiceNo,
                    是否绑定采购订单 = x.IsBindPurchaseOrder ? "是" : "否",
                    采购编码 = x.PurchaseCode,
                    采购主题 = x.PurchaseSubject,
                    供应商名称 = x.SupplierName,
                    采购日期 = x.PurchaseDate?.ToString("yyyy-MM-dd"),
                    入库状态 = x.InboundStatus,
                    已付款金额 = x.PaidAmount,
                    已到票金额 = x.ReceivedAmount,
                    到票状态 = GetReceiptStatusText(x.Status),
                    创建人 = x.CreateName,
                    创建时间 = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    更新人 = x.UpdateName,
                    更新时间 = x.UpdateTime?.ToString("yyyy-MM-dd HH:mm:ss")
                }).ToList();

                var stream = new MemoryStream();
                await stream.SaveAsAsync(exportModels);
                stream.Position = 0;

                var fileName = $"到票数据_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                return File(
                    fileStream: stream,
                    contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sxlsx",
                    fileDownloadName: fileName
                );
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { success = false, message = $"导出失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 获取开票状态的中文文本
        /// </summary>
        private string GetInvoiceStatusText(InvoiceStatus status)
        {
            return status switch
            {
                InvoiceStatus.Uninvoiced => "未开票",
                InvoiceStatus.Invoicing => "开票中",
                InvoiceStatus.Invoiced => "已开票",
                _ => "未知"
            };
        }

        /// <summary>
        /// 获取到票状态的中文文本
        /// </summary>
        private string GetReceiptStatusText(ReceiptStatus status)
        {
            return status switch
            {
                ReceiptStatus.Unreceived => "未到票",
                ReceiptStatus.Receiving => "到票中",
                ReceiptStatus.Received => "已到票",
                _ => "未知"
            };
        }
        #endregion

        #region 导入功能
        /// <summary>
        /// 导入发票数据
        /// </summary>
        [HttpPost("ImportInvoice")]
        public async Task<IActionResult> ImportInvoice(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest(new { success = false, message = "请选择要导入的Excel文件" });
            }

            if (!Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
            {
                return BadRequest(new { success = false, message = "请上传.xlsx格式的Excel文件" });
            }

            try
            {
                var importModels = new List<InvoiceImportDto>();
                using (var stream = file.OpenReadStream())
                {
                    // 先异步读取Excel数据，再转成List
                    var data = await stream.QueryAsync<InvoiceImportDto>();
                    importModels = data.ToList();
                }

                // 验证导入数据
                var validationErrors = ValidateInvoiceImportData(importModels);
                if (validationErrors.Any())
                {
                    return BadRequest(new { success = false, message = "导入数据验证失败", errors = validationErrors });
                }

                // 转换为领域模型并保存
                var invoices = importModels.Select(dto => new Invoice
                {
                    SystemNo = dto.系统编号,
                    InvoiceSubject = dto.开票主题,
                    InvoiceType = dto.发票类型,
                    InvoiceDate = dto.开票日期,
                    IsBindSalesOrder = dto.是否绑定销售订单 == "是",
                    Payee = dto.收票方,
                    InvoiceNo = dto.发票号,
                    SalesOrderNo = dto.销售单号,
                    SalesOrderSubject = dto.销售订单主题,
                    Amount = dto.发票金额,
                    OutboundStatus = dto.出库状态,
                    Status = GetInvoiceStatusFromText(dto.开票状态),
                    CreateName = "系统导入",
                    CreateTime = DateTime.Now,
                    UpdateName = "系统导入",
                    UpdateTime = DateTime.Now,
                    Isdel = false
                }).ToList();

                await _invoiceRepository.AddRangeAsync(invoices);

                return Ok(new { success = true, message = $"成功导入{invoices.Count}条发票数据" });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { success = false, message = $"导入失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 导入到票数据
        /// </summary>
        [HttpPost("ImportReceipt")]
        public async Task<IActionResult> ImportReceipt(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest(new { success = false, message = "请选择要导入的Excel文件" });
            }

            if (!Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
            {
                return BadRequest(new { success = false, message = "请上传.xlsx格式的Excel文件" });
            }

            try
            {
                var importModels = new List<ReceiptImportDto>();
                using (var stream = file.OpenReadStream())
                {
                    var data = await stream.QueryAsync<ReceiptImportDto>();
                    importModels = data.ToList();

                }

                // 验证导入数据
                var validationErrors = ValidateReceiptImportData(importModels);
                if (validationErrors.Any())
                {
                    return BadRequest(new { success = false, message = "导入数据验证失败", errors = validationErrors });
                }

                // 转换为领域模型并保存
                var receipts = importModels.Select(dto => new Receipt
                {
                    SytemNo = dto.到票单号,
                    ReceiptSubject = dto.到票主题,
                    ReceiptDate = dto.到票日期,
                    InvoiceIssuer = dto.开票方,
                    InvoiceNo = dto.发票号,
                    IsBindPurchaseOrder = dto.是否绑定采购订单 == "是",
                    PurchaseCode = dto.采购编码,
                    PurchaseSubject = dto.采购主题,
                    SupplierName = dto.供应商名称,
                    PurchaseDate = dto.采购日期,
                    InboundStatus = dto.入库状态,
                    PaidAmount = dto.已付款金额,
                    ReceivedAmount = dto.已到票金额,
                    Status = GetReceiptStatusFromText(dto.到票状态),
                    CreateName = "系统导入",
                    CreateTime = DateTime.Now,
                    UpdateName = "系统导入",
                    UpdateTime = DateTime.Now,
                    Isdel = false
                }).ToList();

                await _receiptRepository.AddRangeAsync(receipts);

                return Ok(new { success = true, message = $"成功导入{receipts.Count}条到票数据" });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new { success = false, message = $"导入失败：{ex.Message}" });
            }
        }

        /// <summary>
        /// 验证发票导入数据
        /// </summary>
        private List<string> ValidateInvoiceImportData(List<InvoiceImportDto> importModels)
        {
            var errors = new List<string>();

            if (!importModels.Any())
            {
                errors.Add("Excel文件中没有数据");
                return errors;
            }

            for (int i = 0; i < importModels.Count; i++)
            {
                var rowNum = i + 2; // Excel行号从1开始，标题行是1，数据行从2开始
                var dto = importModels[i];

                if (string.IsNullOrWhiteSpace(dto.开票单号))
                {
                    errors.Add($"第{rowNum}行：开票单号不能为空");
                }

                if (string.IsNullOrWhiteSpace(dto.发票号))
                {
                    errors.Add($"第{rowNum}行：发票号不能为空");
                }

                if (dto.发票金额 <= 0)
                {
                    errors.Add($"第{rowNum}行：发票金额必须大于0");
                }

                if (string.IsNullOrWhiteSpace(dto.开票状态) ||
                    !new[] { "未开票", "开票中", "已开票" }.Contains(dto.开票状态))
                {
                    errors.Add($"第{rowNum}行：开票状态无效，必须是'未开票'、'开票中'或'已开票'");
                }
            }

            return errors;
        }

        /// <summary>
        /// 验证到票导入数据
        /// </summary>
        private List<string> ValidateReceiptImportData(List<ReceiptImportDto> importModels)
        {
            var errors = new List<string>();

            if (!importModels.Any())
            {
                errors.Add("Excel文件中没有数据");
                return errors;
            }

            for (int i = 0; i < importModels.Count; i++)
            {
                var rowNum = i + 2; // Excel行号从1开始，标题行是1，数据行从2开始
                var dto = importModels[i];

                if (string.IsNullOrWhiteSpace(dto.到票单号))
                {
                    errors.Add($"第{rowNum}行：到票单号不能为空");
                }

                if (string.IsNullOrWhiteSpace(dto.发票号))
                {
                    errors.Add($"第{rowNum}行：发票号不能为空");
                }

                if (dto.已到票金额 <= 0)
                {
                    errors.Add($"第{rowNum}行：已到票金额必须大于0");
                }

                if (string.IsNullOrWhiteSpace(dto.到票状态) ||
                    !new[] { "未到票", "到票中", "已到票" }.Contains(dto.到票状态))
                {
                    errors.Add($"第{rowNum}行：到票状态无效，必须是'未到票'、'到票中'或'已到票'");
                }
            }

            return errors;
        }

        /// <summary>
        /// 从中文文本获取开票状态枚举
        /// </summary>
        private InvoiceStatus GetInvoiceStatusFromText(string statusText)
        {
            return statusText switch
            {
                "未开票" => InvoiceStatus.Uninvoiced,
                "开票中" => InvoiceStatus.Invoicing,
                "已开票" => InvoiceStatus.Invoiced,
                _ => throw new ArgumentException($"无效的开票状态: {statusText}")
            };
        }

        /// <summary>
        /// 从中文文本获取到票状态枚举
        /// </summary>
        private ReceiptStatus GetReceiptStatusFromText(string statusText)
        {
            return statusText switch
            {
                "未到票" => ReceiptStatus.Unreceived,
                "到票中" => ReceiptStatus.Receiving,
                "已到票" => ReceiptStatus.Received,
                _ => throw new ArgumentException($"无效的到票状态: {statusText}")
            };
        }
        #endregion

    }
}